package com.example.test.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.example.test.Dao.CustomersDao;
import com.example.test.Dao.GoodsDao;
import com.example.test.Dao.OrderGoodsDao;
import com.example.test.bean.BaseOrders;
import com.example.test.bean.Customers;
import com.example.test.bean.DTO.input.OrderInputDTO;
import com.example.test.bean.DTO.output.BaseOrdersListOutputDTO;
import com.example.test.bean.DTO.output.GoodsListOutputDTO;
import com.example.test.bean.DTO.output.OrderGoodsListOutputDTO;
import com.example.test.bean.DTO.output.OrderOutputDTO;
import com.example.test.bean.OrderGoods;
import com.example.test.bean.Users;
import com.example.test.common.model.PageModel;
import com.example.test.common.model.R;
import com.example.test.mapper.BaseOrdersMapper;
import com.example.test.mapper.CustomersMapper;
import com.example.test.mapper.OrderGoodsMapper;
import com.example.test.mapper.UsersMapper;
import com.example.test.service.BaseOrdersService;
import com.example.test.service.CustomersService;
import com.example.test.service.OrderGoodsService;
import com.example.test.service.UsersService;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 基础订单表 服务实现类
 * </p>
 *
 * @author dz
 * @since 2022-04-10
 */
@Service
public class BaseOrdersServiceImpl extends ServiceImpl<BaseOrdersMapper, BaseOrders> implements BaseOrdersService {

    @Resource
    private BaseOrdersMapper baseOrdersMapper;
    @Resource
    private OrderGoodsMapper orderGoodsMapper;
    @Autowired
    private CustomersMapper customersMapper;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private CustomersService customersService;
    @Autowired
    private OrderGoodsService orderGoodsService;
    @Autowired
    private UsersMapper usersMapper;

    private final Logger LOGGER = LoggerFactory.getLogger(BaseOrdersService.class);
    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig.Builder("jdbc:mysql://localhost:3306/daidb?serverTimezone=GMT%2B8", "root", "123456")
            .typeConvert(new MySqlTypeConvert());
    //根据keyword查询基础表单 用于order查看界面
    public R getOrderByKeyword(String keyword, PageModel pageModel) {
        try {
            Long current = pageModel.getCurrent();
            Long size = pageModel.getSize();
            Long offset = (current - 1) * size;
            //获得基础订单list
            List<BaseOrdersListOutputDTO> orderList = baseOrdersMapper.getOrderByKeyword(keyword, size, offset);
            return R.success(orderList);
        } catch (Exception e) {
            LOGGER.error("", e);
            return R.error("查询表单失败:" + e.getMessage());
        }
    }

    //根据id查询表单详细信息
    public R getOrder(Long orderId) {
        try {
            //获取基础表单
            BaseOrdersListOutputDTO order = baseOrdersMapper.getSelectOrder(orderId);
            if (order == null) {
                return R.error("未查询到相应订单");
            } else {
                //获取订单内商品表单
                List<OrderGoodsListOutputDTO> oGoods = orderGoodsMapper.getoGoodsById(orderId);
                order.setOrderGoods(oGoods);
            }
            return R.success(order);
        } catch (Exception e) {
            LOGGER.error("", e);
            return R.error("查询表单失败:" + e.getMessage());
        }
    }

    //插入表单
    @Transactional(rollbackFor = RuntimeException.class)
    public R addOrder(OrderOutputDTO orderOutputDTO) {
        try {
            Date time = new Date();
            Customers customer = new Customers();
            BaseOrders newBaseOrder = new BaseOrders();
            Double countCost = 0.0;
            String customerName = orderOutputDTO.getCustomerName();
            String adress = orderOutputDTO.getShipAddress();
            //初始化序列号
            String serialNumber = "order"+time + customerName;
            //初始化客户信息
            if (adress != null) {
                customer.setAdress(adress);
            }
            customer.setCreateTime(time);
            customer.setCustomerName(customerName);
            customer.setPhone(orderOutputDTO.getPhone());
            //检索customerName，如果没有该用户，则新建
            if (customersMapper.getCustomByName(customerName) == null) {
                int addCustNum = customersMapper.insert(customer);
                if (addCustNum == 0) {
                    return R.error("添加客户失败");
                }
            }
            //获得当前用户(用于最后添加金额)
            customer = customersMapper.getCustomByName(customerName);
            // 如果没有填写地址，则搜索客户的默认地址，若还没有，则返回错误
            if (customer.getAdress() == null) {
                return R.error("地址为空！");
            }
            //设置orderstate为未完成状态
            orderOutputDTO.setOrderState("未完成");
            //获取baseOrder内容
            newBaseOrder.setSerialNumber(serialNumber);
            newBaseOrder.setShipAddress(adress);
            newBaseOrder.setCreateTime(time);
            newBaseOrder.setCostomerId(customer.getCustomerId());
            newBaseOrder.setOrderState("未完成");
            newBaseOrder.setRemarks(orderOutputDTO.getRemarks());
            newBaseOrder.setDeleted(false);
            //插入baseOrder
            int addBaseOrder = baseOrdersMapper.insert(newBaseOrder);
            if (addBaseOrder == 0) {
                return R.error("添加失败: addBaseOrder = 0");
            }
            Long orderId = baseOrdersMapper.getOrderIdBySerial(serialNumber);
            //获得表单内商品List
            List<OrderGoods> orderGoodList = orderOutputDTO.getOrderGoods();
            //判断是否为空
            if (orderGoodList.size() < 1) {
                return R.error("订单为空！");
            }
            //循环判断购买商品量是否大于库存，如果小于，则将库存减去；如果大于 修改isEnough标记
            for (OrderGoods orderGood : orderGoodList) {
                String goodName = orderGood.getGoodName();
                //补足orderGood的字段
                orderGood.setOrderId(orderId);
                orderGood.setGoodId(goodsDao.getGoodIdByName(goodName));
                //获取同名商品 仓库内的存储数据，计算两者数量差判断库存是否充足
                GoodsListOutputDTO storeGood = goodsDao.getByName(goodName);
                Long caculateNum = storeGood.getGoodsRemain() - orderGood.getGoodNum();
                if (caculateNum > 0) {
                    orderGood.setIsEnough(true);
                } else {
                    orderGood.setIsEnough(false);
                }
                //提交goodOrder

                Boolean addGoodOrder = orderGoodsService.save(orderGood);
                if (addGoodOrder == Boolean.FALSE) {
                    return R.error("添加订单-订单商品详情添加失败");
                }
                //将orderGoods的价格相加计算，获得订单总价
                countCost = countCost + orderGood.getSumSell();
            }
            //更新baseOrder
            newBaseOrder.setSellMoney(countCost);
            newBaseOrder.setOrderId(orderId);
            int updateBaseOrder = baseOrdersMapper.updateById(newBaseOrder);
            if (updateBaseOrder == 0) {
                return R.error("更新失败: updateOrder = 0");
            }
            return R.success("添加订单成功！");
        } catch (Exception e) {
            LOGGER.error("", e);
            throw e;
//            return R.error("添加表单失败:" + e.getMessage());
        }

    }

    //更新表单
    public R updateOrder(OrderInputDTO orderInputDTO) {
        try {
            Date time = new Date();
            Customers customer = new Customers();
            BaseOrders newBaseOrder = new BaseOrders();
            Double countCost = 0.0;
            String customerName = orderInputDTO.getCustomerName();
            String adress = orderInputDTO.getShipAddress();
            Long custId = customersMapper.getCustIdByName(customerName);
            //初始化客户信息
            customer.setCreateTime(time);
            customer.setPhone(orderInputDTO.getPhone());
            //检索custId，如果没有该用户，则新建,如果有
            if (custId == null) {
                if (adress != null) {
                    customer.setAdress(adress);
                }
                int addCustNum = customersMapper.insert(customer);
                if (addCustNum == 0) {
                    return R.error("添加客户失败");
                }
            } else {
                customer.setCustomerId(custId);
                int updateCUstNum = customersMapper.updateById(customer);
                if (updateCUstNum == 0) {
                    return R.error("更新客户失败");
                }
            }
            //获得当前用户(用于最后添加金额)
            customer = customersMapper.getCustomByName(customerName);
            //获取baseOrder内容
            Long orderId = orderInputDTO.getOrderId();
            newBaseOrder.setOrderId(orderId);
            newBaseOrder.setShipAddress(adress);
            newBaseOrder.setUpdateTime(time);
            newBaseOrder.setCostomerId(customer.getCustomerId());
            newBaseOrder.setRemarks(orderInputDTO.getRemarks());
            //获得表单内商品List
            List<OrderGoods> orderGoodList = orderInputDTO.getOrderGoods();
            //删除原有的对应商品表单
            LambdaQueryWrapper<OrderGoods> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderGoods::getOrderId,orderId);
            orderGoodsMapper.delete(wrapper);
            //循环判断购买商品量是否大于库存，如果小于，则将库存减去；如果大于 修改isEnough标记
            for (OrderGoods orderGood : orderGoodList) {
                String goodName = orderGood.getGoodName();
                //补足orderGood的字段
                orderGood.setOrderId(orderId);
                orderGood.setGoodId(goodsDao.getGoodIdByName(goodName));
                //获取同名商品 仓库内的存储数据，计算两者数量差判断库存是否充足
                GoodsListOutputDTO storeGood = goodsDao.getByName(goodName);
                Long caculateNum = storeGood.getGoodsRemain() - orderGood.getGoodNum();
                if (caculateNum > 0) {
                    orderGood.setIsEnough(true);
                } else {
                    orderGood.setIsEnough(false);
                }
                //提交goodOrder
                int updateGoodOrder = orderGoodsMapper.insert(orderGood);
                if (updateGoodOrder == 0) {
                    return R.error("更新订单-订单商品详情更新失败");
                }
                //将orderGoods的价格相加计算，获得订单总价
                countCost = countCost + orderGood.getSumSell();
            }
            //更新baseOrder
            newBaseOrder.setSellMoney(countCost);
            int updateBaseOrder = baseOrdersMapper.updateById(newBaseOrder);
            if (updateBaseOrder == 0) {
                return R.error("更新失败: updateOrder = 0");
            }
            return R.success("更新订单成功！");
        } catch (Exception e) {
            LOGGER.error("", e);
            return R.error("更新表单失败:" + e.getMessage());
        }

    }

    //    完成表单
    public R finishOrder(OrderInputDTO orderInputDTO) {
        try {
            Date time = new Date();
            Customers customer = new Customers();
            BaseOrders newBaseOrder = new BaseOrders();
            Double countCost = 0.0;
            String customerName = orderInputDTO.getCustomerName();
            String adress = orderInputDTO.getShipAddress();
            Long custId = customersMapper.getCustIdByName(customerName);
            //初始化客户信息
            customer.setCreateTime(time);
            customer.setPhone(orderInputDTO.getPhone());
            //检索custId，如果没有该用户，则新建,如果有
            if (custId == null) {
                if (adress != null) {
                    customer.setAdress(adress);
                }
                int addCustNum = customersMapper.insert(customer);
                if (addCustNum == 0) {
                    return R.error("添加客户失败");
                }
            } else {
                customer.setCustomerId(custId);
                int updateCUstNum = customersMapper.updateById(customer);
                if (updateCUstNum == 0) {
                    return R.error("更新客户失败");
                }
            }
            //获得当前用户(用于最后添加金额)
            customer = customersMapper.getCustomByName(customerName);
            Users users = usersMapper.getUserByNickname(orderInputDTO.getUserNickname());
            Long userId = users.getUserId();
            //获取baseOrder内容
            Long orderId = orderInputDTO.getOrderId();
            newBaseOrder.setOrderId(orderId);
            newBaseOrder.setShipAddress(adress);
            newBaseOrder.setUpdateTime(time);
            newBaseOrder.setOrderState("完成");
            newBaseOrder.setOrderApprovalId(userId);
            newBaseOrder.setCostomerId(customer.getCustomerId());
            newBaseOrder.setRemarks(orderInputDTO.getRemarks());
            //获得表单内商品List
            List<OrderGoods> orderGoodList = orderInputDTO.getOrderGoods();
            //删除原有的对应商品表单
            LambdaQueryWrapper<OrderGoods> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderGoods::getOrderId,orderId);
            orderGoodsMapper.delete(wrapper);
            //循环判断购买商品量是否大于库存，如果小于，则将库存减去；如果大于 修改isEnough标记

            for (OrderGoods orderGood : orderGoodList) {
                String goodName = orderGood.getGoodName();
                //补足orderGood的字段
                orderGood.setOrderId(orderId);
                orderGood.setGoodId(goodsDao.getGoodIdByName(goodName));
                //获取同名商品 仓库内的存储数据，计算两者数量差判断库存是否充足
                GoodsListOutputDTO storeGood = goodsDao.getByName(goodName);
                Long caculateNum = storeGood.getGoodsRemain() - orderGood.getGoodNum();
                if (caculateNum > 0) {
                    orderGood.setIsEnough(true);
                } else {
                    orderGood.setIsEnough(false);
                }
                //提交goodOrder
                int updateGoodOrder = orderGoodsMapper.insert(orderGood);
                if (updateGoodOrder == 0) {
                    return R.error("更新订单-订单商品详情更新失败");
                }
                //将orderGoods的价格相加计算，获得订单总价
                countCost = countCost + orderGood.getSumSell();
            }
            //更新baseOrder
            newBaseOrder.setSellMoney(countCost);
            int updateBaseOrder = baseOrdersMapper.updateById(newBaseOrder);
            if (updateBaseOrder == 0) {
                return R.error("更新失败: updateOrder = 0");
            }
            return R.success("更新订单成功！");
        } catch (Exception e) {
            LOGGER.error("", e);
            return R.error("完成表单失败:" + e.getMessage());
        }

    }

    //删除表单
    public R deleteOrder(Long orderId) {
        try {
            Date time = new Date();
            BaseOrders oldBaseOrder = baseOrdersMapper.getBaseById(orderId);
            oldBaseOrder.setDeleted(true);
            oldBaseOrder.setDeletedTime(time);
            int deleteOrder = baseOrdersMapper.updateById(oldBaseOrder);
            if (deleteOrder == 0) {
                return R.error("删除失败");
            }
            return R.success("删除成功!orderId = " + orderId);
        } catch (Exception e) {
            LOGGER.error("", e);
            return R.error("删除表单失败:" + e.getMessage());
        }
    }

    @Override
    public R createAll() {
        FastAutoGenerator.create(DATA_SOURCE_CONFIG)
                .globalConfig(builder -> {
                    builder.author("dz") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("D://"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.example") // 设置父包名
                            .moduleName("test") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("order_goods");// 设置需要生成的表名
//                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                })
                .templateEngine(new VelocityTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();

        return null;
    }


}
